package yxy.cherry.paycenter.util;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.*;

public class wxUtil {
    /**
     *  map转成xml
     * @param parm
     * @param isAddCDATA
     * @return
     */
    public static String mapToXml(Map<String, String> parm, boolean isAddCDATA) {

    	//首先要对map进行ASCLL码排序
        ArrayList<Map.Entry<String,String>> arrayList = new ArrayList<>(parm.entrySet());
        Collections.sort(arrayList, new Comparator<Map.Entry<String, String>>() {
            @Override
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });

        StringBuffer strbuff = new StringBuffer("<xml>");


        if (parm != null && !parm.isEmpty()) {
            for (Map.Entry<String, String> entry : arrayList) {
                strbuff.append("<").append(entry.getKey()).append(">");
                if (isAddCDATA) {
                    strbuff.append("<![CDATA[");
                    if (StringUtils.isNotEmpty(entry.getValue())) {
                        strbuff.append(entry.getValue());
                    }
                    strbuff.append("]]>");
                } else {
                    if (StringUtils.isNotEmpty(entry.getValue())) {
                        strbuff.append(entry.getValue());
                    }
                }
                strbuff.append("</").append(entry.getKey()).append(">");
            }
        }
        return strbuff.append("</xml>").toString();
    }

    /**
     * 获取随机字符串 Nonce Str
     * 随机字符从symbols获取
     * SecureRandom真随机数
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new SecureRandom();
        char[] nonceChars = new char[16];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = symbols.charAt(random.nextInt(symbols.length()));
        }
        return new String(nonceChars);
    }
    
	public static String getMD5(String str) {
		try {
			// 生成一个MD5加密计算摘要
			MessageDigest md = MessageDigest.getInstance("MD5");
			// 计算md5函数
			md.update(str.getBytes("UTF-8"));
			// digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
			// BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
			// return new BigInteger(1, md.digest()).toString(16);
			byte[] md5sum = md.digest();
			return toHex(md5sum);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}

	public static String toHex(byte[] data) {
		char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
		char[] chars = new char[data.length * 2];
		for (int i = 0; i < data.length; i++) {
			chars[i * 2] = HEX_DIGITS[(data[i] >> 4) & 0xf];
			chars[i * 2 + 1] = HEX_DIGITS[data[i] & 0xf];
		}
		return new String(chars);
	}
	
	/**
	 *  生成创建订单时的透传参数
	 * @param uid	玩家游戏唯一标识
	 * @param dataid	 商品id
	 * @param subchannel	标记渠道 小渠道
	 * @return
	 */
	public static String produceExtend(String sid, String uid, String dataid, String subchannel) {
		StringBuilder sb = new StringBuilder();
		sb.append("sid=").append(sid).append(";").append("uid=").append(uid).append(";")
				.append("id=").append(dataid).append(";").append("subchannel=").append(subchannel);
		return sb.toString();
	}
	
	public static String addExtend(String extend, String key, String value) {
		StringBuilder sb = new StringBuilder();
		sb.append(extend).append(";").append(key).append("=").append(value);
		return sb.toString();
	}
	
//	public static String xmlToJson(String xml) {
//        //创建 XMLSerializer对象
//        XMLSerializer xmlSerializer = new XMLSerializer();
//        //将xml转为json（注：如果是元素的属性，会在json里的key前加一个@标识）
//        String result = xmlSerializer.read(xml).toString();
//        //输出json内容
//        System.out.println(result);
//		return result;
//	}
	
	public static JSONObject xml2Json(String xmlStr) throws DocumentException{
        Document doc= DocumentHelper.parseText(xmlStr);
        JSONObject json=new JSONObject();
        dom4j2Json(doc.getRootElement(), json);
        return json;
    }

	/**
     * xml转json
     * @param element
     * @param json
     */
    public static void dom4j2Json(Element element,JSONObject json){
        //如果是属性
        for(Object o:element.attributes()){
            Attribute attr=(Attribute)o;
            if(!isEmpty(attr.getValue())){
                json.put("@"+attr.getName(), attr.getValue());
            }
        }
        List<Element> chdEl=element.elements();
        if(chdEl.isEmpty()&&!isEmpty(element.getText())){//如果没有子元素,只有一个值
            json.put(element.getName(), element.getText());
        }

        for(Element e:chdEl){//有子元素
            if(!e.elements().isEmpty()){//子元素也有子元素
                JSONObject chdjson=new JSONObject();
                dom4j2Json(e,chdjson);
                Object o=json.get(e.getName());
                if(o!=null){
                    JSONArray jsona=null;
                    if(o instanceof JSONObject){//如果此元素已存在,则转为jsonArray
                        JSONObject jsono=(JSONObject)o;
                        json.remove(e.getName());
                        jsona=new JSONArray();
                        jsona.add(jsono);
                        jsona.add(chdjson);
                    }
                    if(o instanceof JSONArray){
                        jsona=(JSONArray)o;
                        jsona.add(chdjson);
                    }
                    json.put(e.getName(), jsona);
                }else{
                    if(!chdjson.isEmpty()){
                        json.put(e.getName(), chdjson);
                    }
                }


            }else{//子元素没有子元素
                for(Object o:element.attributes()){
                    Attribute attr=(Attribute)o;
                    if(!isEmpty(attr.getValue())){
                        json.put("@"+attr.getName(), attr.getValue());
                    }
                }
                if(!e.getText().isEmpty()){
                    json.put(e.getName(), e.getText());
                }
            }
        }
    }

    public static boolean isEmpty(String str) {

        if (str == null || str.trim().isEmpty() || "null".equals(str)) {
            return true;
        }
        return false;
    }
	
    
    
//	public static void main(String[] str) {
//		String xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code>\r\n" + 
//				"<return_msg><![CDATA[OK]]></return_msg>\r\n" + 
//				"<appid><![CDATA[wx3226b21e8c402f0f]]></appid>\r\n" + 
//				"<mch_id><![CDATA[1602430099]]></mch_id>\r\n" + 
//				"<nonce_str><![CDATA[BcM3PqJIAJF1AVrr]]></nonce_str>\r\n" + 
//				"<sign><![CDATA[D9586CDA44C2C8FF27CAA434642BC35E]]></sign>\r\n" + 
//				"<result_code><![CDATA[SUCCESS]]></result_code>\r\n" + 
//				"<prepay_id><![CDATA[wx15172815929644f4376888c47d24ba0000]]></prepay_id>\r\n" + 
//				"<trade_type><![CDATA[JSAPI]]></trade_type>\r\n" + 
//				"</xml>";
//		try {
//			JSONObject info = xml2Json(xml);
//			System.out.println(info);
//		} catch (DocumentException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}
	

}